package org.example;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.List;
public class ClassLoadProcessor {
    //target目录的文件路径
    public static final String TARGET_PATH="D:\\javaWeb\\javaWEBcode\\MAVEN\\demo005\\target";
    public static final String SERVICE_METHOD="service";
    public static final String Servlet="Servlet";
    //加载指定目录下的class文件并调用方法执行
    public static void loadClass(String jspName,MyHttpRequest req,MyHttpResponse resp) throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //jsp文件名第一个字符大写拼接上Servlet
        StringBuilder builder = new StringBuilder().append(Character.toUpperCase(jspName.charAt(0)))
                .append(jspName.substring(1))
                .append(Servlet);
        String jspServletName= builder.toString();
        //实例化类加载器
        URLClassLoader loader=null;
        //创建一个url数组,用于指定类加载器的搜索路径
        URL[] urls=new URL[1];
        URLStreamHandler streamHandler=null;
        //target目录文件
        File targetPath= new File(TARGET_PATH);
        //获取类路径文件
        File classesPath = new File(targetPath, "classes");
        String repository=(
                new URL("file",null,classesPath.getCanonicalPath()+File.separator)
        ).toString();
        urls[0]=new URL(null,repository,streamHandler);
        //初始化类加载器并指定加载路径
        loader=new URLClassLoader(urls);
        //获取当下classes目录下的所有文件
        List<File> files=getAllFile(classesPath);
        for (File file : files) {
            //获取文件的绝对路径
            String path = file.getPath();
            path=path.replace(classesPath.getPath()+"\\","");
            //将文件路径的后缀名.class去掉
            path=path.replace(".class","");
            //将文件路径中的\替换为.
            path=path.replace("\\",".");
            String servletClassName=path.substring(path.lastIndexOf('.')+1);
            //加载指定的类（类的全限定名）
            Class<?> servletClass=loader.loadClass(path);
            //利用反射判断该对象是否是继承自httpServlet
            if(HttpServlet.class.isAssignableFrom(servletClass)){
                //判断是否存在jsp对应的servlet.class文件
                if(jspServletName.equals(servletClassName)){
                    //利用反射获取Class对象里面的service方法
                    Method method = servletClass.getMethod(SERVICE_METHOD, MyHttpRequest.class, MyHttpResponse.class);
                    //调用方法执行
                    method.invoke(servletClass.newInstance(),req,resp);
                }
            }
        }
    }
    //根据传入的classesPath获取所有的servlet
    public static  List<File> getAllFile(File srcFile){
        List<File> result=new ArrayList<>();
        File[] files = srcFile.listFiles();
        if(files!=null){
            for (File file : files) {
                //判断是否是目录
                if(file.isDirectory()){
                    //递归遍历
                    result.addAll(getAllFile(file));
                }else{
                    result.add(file);
                }
            }
        }
        return result;
    }

}
